package cn.iocoder.yudao.module.agent.dal.mysql.user;

import java.util.*;

import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.agent.dal.dataobject.user.AgentUserDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.agent.controller.admin.user.vo.*;

/**
 * 代理人 Mapper
 *
 * @author 曹建伟
 */
@Mapper
public interface AgentUserMapper extends BaseMapperX<AgentUserDO> {

    default PageResult<AgentUserDO> selectPage(AgentUserPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<AgentUserDO>()
                .eqIfPresent(AgentUserDO::getEnabled, reqVO.getEnabled())
                .betweenIfPresent(AgentUserDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(AgentUserDO::getId));
    }

    default List<AgentUserDO> selectList(AgentUserExportReqVO reqVO) {
        return selectList(new LambdaQueryWrapperX<AgentUserDO>()
                .eqIfPresent(AgentUserDO::getEnabled, reqVO.getEnabled())
                .betweenIfPresent(AgentUserDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(AgentUserDO::getId));
    }

    /**
     * 更新用户冻结佣金（增加）
     *
     * @param userId        用户编号
     * @param incrCount 增加冻结佣金（正数）
     */
    default void updateFrozenPriceIncr(Long userId, Integer incrCount) {
        Assert.isTrue(incrCount > 0);
        LambdaUpdateWrapper<AgentUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<AgentUserDO>()
                .setSql(" frozen_brokerage = frozen_brokerage + " + incrCount)
                .eq(AgentUserDO::getUserId, userId);
        update(null, lambdaUpdateWrapper);
    }
    /**
     * 更新用户冻结佣金（减少）
     * 注意：理论上冻结佣金可能已经解冻，这时会扣出负数，确保平台不会造成损失
     *
     * @param userId        用户编号
     * @param incrCount 减少冻结佣金（负数）
     */
    default void updateFrozenPriceDecr(Long userId, Integer incrCount) {
        Assert.isTrue(incrCount < 0);
        LambdaUpdateWrapper<AgentUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<AgentUserDO>()
                .setSql(" frozen_brokerage = frozen_brokerage + " + incrCount) // 负数，所以使用 + 号
                .eq(AgentUserDO::getUserId, userId);
        update(null, lambdaUpdateWrapper);
    }

    /**
     * 更新用户佣金（增加）
     *
     * @param userId        用户编号
     * @param incrCount 增加佣金（正数）
     */
    default void updatePriceIncr(Long userId, Integer incrCount) {
        Assert.isTrue(incrCount > 0);
        LambdaUpdateWrapper<AgentUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<AgentUserDO>()
                .setSql(" brokerage = brokerage + " + incrCount)
                .eq(AgentUserDO::getUserId, userId);
        update(null, lambdaUpdateWrapper);
    }

    /**
     * 更新用户佣金（减少）
     *
     * @param userId        用户编号
     * @param incrCount 增加冻结佣金（负数）
     */
    default int updatePriceDecr(Long userId, Integer incrCount) {
        Assert.isTrue(incrCount < 0);
        LambdaUpdateWrapper<AgentUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<AgentUserDO>()
                .setSql(" brokerage = brokerage + " + incrCount) // 负数，所以使用 + 号
                .eq(AgentUserDO::getUserId, userId);
        return update(null, lambdaUpdateWrapper);
    }

    /**
     * 更新用户冻结佣金（减少）, 更新用户佣金（增加）
     *
     * @param id        用户编号
     * @param incrCount 减少冻结佣金（负数）
     * @return 更新条数
     */
    default int updateFrozenPriceDecrAndPriceIncr(Long id, Integer incrCount) {
        Assert.isTrue(incrCount < 0);
        LambdaUpdateWrapper<AgentUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<AgentUserDO>()
                .setSql(" frozen_brokerage = frozen_brokerage + " + incrCount + // 负数，所以使用 + 号
                        ", brokerage = brokerage + " + -incrCount) // 负数，所以使用 - 号
                .eq(AgentUserDO::getUserId, id)
                .ge(AgentUserDO::getFrozenBrokerage, -incrCount); // cas 逻辑
        return update(null, lambdaUpdateWrapper);
    }

    /**
     * 总提现金额增加
     *
     * @param userId        用户编号
     * @param incrCount 增加的金额 > 0
     * @return 更新条数
     */
    default int withdrawBrokerageIncr(Long userId, Integer incrCount) {
        Assert.isTrue(incrCount > 0);

        LambdaUpdateWrapper<AgentUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<AgentUserDO>()
                .setSql(" withdraw_brokerage = withdraw_brokerage + " + incrCount)
                .eq(AgentUserDO::getUserId, userId);

        return update(null, lambdaUpdateWrapper);
    }

}
